package bpd;

import static org.junit.Assert.assertTrue;
import net.sf.robocode.io.Logger;
import bpd.test.RobotTestBed;
import robocode.control.events.BattleCompletedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.snapshot.IRobotSnapshot;

/**
 * Illustrates JUnit testing of the Robocode robot PanzerBot. This test simply verifies that this
 * robot will move to the center of the battlefield if it hits a wall.
 * 
 * @author BJ Peter DeLaCruz
 * @version 1.0
 */
public class TestPanzerBotMoveToCenter extends RobotTestBed {
  /** True if the robot hit a wall during the test case. */
  boolean visitedWall = false;
  /** True if the robot visited the center of the battlefield during the test case. */
  boolean visitedCenter = false;
  /** Information about the turn during which the robot bumped into a wall. */
  String bumpedInfo = "";
  /** Information about the turn during which the robot moved to the center of the battlefield. */
  String movedInfo = "";

  /**
   * Specifies that Walls and PanzerBot are to be matched up in this test case.
   * 
   * @return A comma-delimited list of robots in this match
   */
  @Override
  public String getRobotNames() {
    return "sample.Walls,bpd.PanzerBot";
  }
  
  /**
   * This test runs for twenty rounds.
   * 
   * @return The number of rounds in this test 
   */
  @Override
  public int getNumRounds() {
    return 20;
  }

  /**
   * After each turn, check to see if PanzerBot hit a wall and visited the center of the
   * battlefield.  If so, set the corresponding flag.
   * 
   * @param event Information about the current state of the battle
   */
  @Override 
  public void onTurnEnded(TurnEndedEvent event) {
    
    int turn = event.getTurnSnapshot().getTurn(); // Get turn number
    IRobotSnapshot robot = event.getTurnSnapshot().getRobots()[1];
    double xPos = robot.getX();
    double yPos = robot.getY();
    
    // Robot is close to the left or right wall.
    if ((xPos > (width - 40)) || xPos < 40) {
      visitedWall = true;
      bumpedInfo = "\n\nBumped into the left or right wall during turn #" + turn;
    }
    // Robot is close to the top or bottom wall.
    else if ((yPos > (height - 40)) || yPos < 40) {
      visitedWall = true;
      bumpedInfo = "\n\nBumped into the top or bottom wall during turn #" + turn;
    }
    
    // Robot is at the center of the battlefield.
    if (Math.floor(xPos) == Math.floor(width / 2.0) &&
        Math.floor(yPos) == Math.floor(height / 2.0)) {
      visitedCenter = true;
      movedInfo = bumpedInfo + "\nMoved to the center (X: " + Math.floor(width / 2.0) + ", Y: ";
      movedInfo += Math.floor(height / 2.0) + ") during turn #" + turn + "\n\n";
    }

  }

  /**
   * Asserts that PanzerBot moved to the center of the battlefield after hitting a wall during the
   * battle.
   * 
   * @param event Details about the completed battle
   */
  @Override
  public void onBattleCompleted(BattleCompletedEvent event) {
    
    assertTrue("Check Wall", visitedWall);
    assertTrue("Check Center", visitedCenter);
    Logger.realOut.print(movedInfo);
    
  }
  
  /**
   * Returns false, thus making the robots always start at a random position each time.
   * 
   * @return False if the battle will not be deterministic, true otherwise
   */
  @Override
  public boolean isDeterministic() {
    return false;
  }
  
}
